package vn.edu.tdt.it.domain;

import java.io.FileInputStream;
import java.sql.PreparedStatement;
import java.util.Iterator;
import java.util.Map.Entry;

import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.MappingJsonFactory;

//[INFO] Inserted: Q18416923   - f/p: 853894/18882 lastnode
//Total lines: 16504907
public class JsonProcessing {
	public static void main(String[] args) throws Exception {
		JsonFactory f = new MappingJsonFactory();
		FileInputStream in = null;
		in = new FileInputStream("d://wiki//20141103.json");
		JsonParser jp = f.createJsonParser(in);
		JsonToken current;
		boolean stop=false;
		int passed = 0;
		int failed = 0;
		String sql = "";
		current = jp.nextToken();
		if (current != JsonToken.START_OBJECT) {
			System.out.println("Error: root should be object: quiting.");
			return;
		}
		while (jp.nextToken() != JsonToken.END_OBJECT) {
			String fieldName = jp.getCurrentName();
			current = jp.nextToken();
			if (fieldName != null)
				/* if (fieldName.equals("entities")) { */
				// if (current == JsonToken.START_ARRAY) {
				
				while (jp.nextToken() != JsonToken.END_ARRAY) {
					String id = "";
					try {

						JsonNode node = jp.readValueAsTree();
						if (node == null || node.get("id") == null
								|| node.get("type") == null) {
							continue;
						}
						id = node.get("id").getTextValue();
						if(!id.equals("Q1623342") && !stop){
							
							continue;
						}
						if(id.equals("Q1623342")){
							stop=true;
							continue;
						}
						String type = node.get("type").getTextValue();
						String lbl = "";
						JsonNode label = node.get("labels");
						if (label != null) {
							JsonNode vn = null;
							if(id.charAt(0) == 'Q'){
								vn = label.get("vi");
							} else {
								vn = label.get("en");
							}
							if (vn != null) {
								lbl = vn.get("value").getTextValue();
							}
						}
						if (lbl.equals("")) {
							continue;
						}
						sql = "insert into entity(id,type,title) values(?,?,?)";

						PreparedStatement stmt2 = StaticConnection
								.getPreparedStatement(sql);
						stmt2.setString(1, id);
						stmt2.setString(2, type);
						stmt2.setString(3, lbl);
						stmt2.executeUpdate();
						stmt2.close();
						JsonNode alias = node.get("aliases");
						if (alias != null) {
							JsonNode vn = null;
							if(id.charAt(0) == 'Q'){
								vn =  alias.get("vi");
							} else {
								vn =  alias.get("en");
							}
							
							if (vn != null) {
								Iterator<JsonNode> vnarr = vn.getElements();
								while (vnarr.hasNext()) {
									JsonNode temp = vnarr.next();
									sql = "insert into alias(id,txt) values(?,?)";

									PreparedStatement stmt3 = StaticConnection
											.getPreparedStatement(sql);
									stmt3.setString(1, id);
									stmt3.setString(2, temp.get("value")
											.getTextValue());
									stmt3.executeUpdate();
									stmt3.close();
								}
							}
						}
						JsonNode prop = node.get("claims");
						if (prop != null) {
							Iterator<Entry<String, JsonNode>> vn = prop
									.getFields();
							while (vn.hasNext()) {
								Entry<String, JsonNode> temp = vn.next();
								JsonNode jnode = temp.getValue();
								String pid = temp.getKey();
								if (jnode != null) {
									Iterator<JsonNode> vnarr = jnode
											.getElements();
									while (vnarr.hasNext()) {
										JsonNode nn = vnarr.next();
										nn = nn.get("mainsnak");
										String nn_type = "";
										if (nn.get("datatype") != null) {
											nn_type = nn.get("datatype")
													.getTextValue();
										}
										String txt = "";
										nn = nn.get("datavalue");
										if (nn != null
												&& nn.get("value") != null)
											if (nn_type.equals("wikibase-item")) {
												nn = nn.get("value");
												txt = "Q"
														+ nn.get("numeric-id")
																.asInt();
											} else if (nn_type.equals("time")) {
												nn = nn.get("value");
												txt = nn.get("time").asText();
											} else if (nn_type.equals("quantity")) {
												txt = nn.get("amount").asText();
											}else {
												txt = nn.get("value")
														.getTextValue();
											}
										if (!nn_type.equals("commonsMedia") && !nn_type.equals("globe-coordinate") 
												&& txt!=null && !txt.equals("")) {
											sql = "insert into property(id,pid,txt,type) values(?,?,?,?)";
											PreparedStatement stmt4 = StaticConnection
													.getPreparedStatement(sql);
											stmt4.setString(1, id);
											stmt4.setString(2, pid);
											stmt4.setString(3, txt);
											stmt4.setString(4, nn_type);
											stmt4.executeUpdate();
											stmt4.close();
										}
									}

								}

							}
						}
						passed++;
						StringBuilder sb = new StringBuilder();
						sb.append("[INFO] Inserted: ");
						sb.append(id);
						sb.append("   - f/p: ");
						sb.append(passed);
						sb.append("/");
						sb.append(failed);
						System.out.println(sb.toString());
						
					} catch (Exception e) {
						failed++;
						StringBuilder sb = new StringBuilder();
						sb.append("[ERROR] Fail to insert: ");
						sb.append(id);
						sb.append("   - f/p: ");
						sb.append(passed);
						sb.append("/");
						sb.append(failed);
						System.err.println(sb.toString());
						
					}
					
				}
			/*
			 * } else { System.err.println("[ERROR] WRONG DATA");
			 * jp.skipChildren(); }
			 */
			/*
			 * } else { System.out.println("[ERROR] WRONG DATA");
			 * jp.skipChildren(); }
			 */

		}
		StaticConnection.getStatement().close();
		StaticConnection.getConnection().close();
	}

}
